<?php
/**
 * Copyright (c) [2019] [吴跃忠]
 * [selibra] is licensed under the Mulan PSL v1.
 * You can use this software according to the terms and conditions of the Mulan PSL v1.
 * You may obtain a copy of Mulan PSL v1 at:
 * http://license.coscl.org.cn/MulanPSL
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v1 for more details.
 */

namespace Selibra\Tools;


use Selibra\Files\Config;

/**
 * Class Tools
 * @package selibra
 */
class Tools
{

    /**
     * @param object $object
     * @return object
     */
    public static function deepCopyObject(object $object): object
    {
        return unserialize(serialize($object));
    }


    /**
     * 通过文件路径获取命名空间地址
     * @param string $filepath
     * @return string|null
     */
    public static function getRealNamespaceByFilepath(string $filepath): ?string
    {
        $namespace = substr(str_replace('/', '\\',
            str_replace(Config::getRootPath(), '',
                str_replace('.php', '', $filepath)
            )
        ), 1);
        // 根据自动加载规则
        if (!class_exists($namespace, false)) {
            // 从对应的目录里面找composer.json
            if (strpos($namespace, 'vendor\\') === 0) {
                // 在依赖包内
                // 再进两个目录获取composer.json
                $namespace = explode('\\', $namespace);
                array_shift($namespace);
                $dir1 = array_shift($namespace);
                $dir2 = array_shift($namespace);
                if (empty($namespace)) {
                    return "";
                }
                $composerJson = Config::getRootPath() . DIRECTORY_SEPARATOR . 'vendor/' . $dir1 . '/' . $dir2 . '/composer.json';
                $namespace = implode('\\', $namespace);
            } else {
                // 在外层，直接获取composer.json
                $composerJson = Config::getRootPath() . DIRECTORY_SEPARATOR . 'composer.json';
            }
            if (file_exists($composerJson)) {
                $composerData = json_decode(file_get_contents($composerJson), true);
                $psr4 = $composerData['autoload']['psr-4'];
                if (!empty($composerData['autoload-dev']) && !empty($composerData['autoload-dev']['psr-4'])) {
                    $devPsr4 = $composerData['autoload-dev']['psr-4'];

                    $devPsr4Dir = array_flip($devPsr4);
                    // 如果在开发库里面，跳过
                    foreach ($devPsr4Dir as $dir => $rootSpace) {
                        if (substr($dir, -1, 1) !== '\\') {
                            $dir .= '/';
                        }
                        $dir = str_replace('/', '\\', $dir);
                        if (strpos($namespace, $dir) === 0) {
                            return '';
                        }
                    }
                }
                $psr4Dir = array_flip($psr4);
                // 排序
                $hierarchy = 0;
                // 排序
                foreach ($psr4Dir as $dir => $rootSpace) {
                    if (substr($dir, -1, 1) !== '/') {
                        $dir .= '/';
                    }
                    $dir = str_replace('/', '\\', $dir);
                    if (strpos($namespace, $dir) === 0 || $dir == '\\') {
                        if (strlen($rootSpace) > 1) {
                            $dirName = str_replace('\\', '/', $dir);
                        }
                        if (substr($rootSpace, -1, 1) === '\\') {
                            $rootSpace = substr($rootSpace, 0, -1);
                        }
                        $composerDir = str_replace('composer.json', $dirName, realpath($composerJson));
                        if (substr($composerDir, -1, 1) === '/') {
                            $composerDir = substr($composerDir, 0, -1);
                        }

                        $namespaceFile = str_replace($composerDir, $rootSpace, $filepath);
                        $namespace = str_replace('/', '\\', str_replace('.php', '', $namespaceFile));
                    }

                }
            }
        }
        return $namespace;
    }


    /**
     * 获取
     * @param string $namespace
     * @return string
     */
    public static function getDecRootNamespace(string $namespace): string
    {
        if (strpos('\\', $namespace) === 0) {
            $namespace = substr($namespace, 1);
        }
        return $namespace;
    }


    /**
     * GO方法封装协程
     * @param \Closure $closure
     */
    public static function go(\Closure $closure)
    {
        go(function () use ($closure) {
            // 记录协程调用
            try {
                // 执行
                $closure();
            } catch (\Throwable $exception) {
                Console::log($exception);
            }
        });
    }
}
